package com.dingup.paike.service.pk.impl;

import com.alibaba.fastjson.JSON;
import com.dingup.api.Util.DateUtil;
import com.dingup.api.adapter.classInfo.ClassInfoAdapter;
import com.dingup.api.bean.page.PageData;
import com.dingup.api.enums.ExamTypeEnum;
import com.dingup.api.model.classInfo.ClassInfo;
import com.dingup.api.model.classInfo.ClassUserInfo;
import com.dingup.api.model.lesson.LessonInfo;
import com.dingup.api.model.lesson.LessonSubjectInfo;
import com.dingup.api.model.student.StudentCourseInformation;
import com.dingup.paike.adapter.pk.PkLessonUserAdapter;
import com.dingup.paike.bean.aobean.StatisticsClassHourAO;
import com.dingup.paike.bean.aobean.StudentStatisticsClassHourAO;
import com.dingup.paike.dao.PkLessonUserMapper;
import com.dingup.paike.enums.PkLessonUserTypeEnum;
import com.dingup.paike.feign.client.classInfo.ClassInfoFeignClient;
import com.dingup.paike.feign.client.student.StudentFeignClient;
import com.dingup.paike.feign.client.user.UserFeignClient;
import com.dingup.paike.service.pk.StatisticsService;
import com.dingup.paike.util.PageDataUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by wancheng on 2018/11/1.
 */
@Service
public class StatisticsServiceImpl implements StatisticsService {

    private static final Logger logger = LoggerFactory.getLogger(StatisticsServiceImpl.class);

    @Autowired
    PkLessonUserMapper pkLessonUserMapper;
    @Autowired
    ClassInfoFeignClient classInfoFeignClient;
    @Autowired
    StudentFeignClient studentFeignClient;
    @Autowired
    UserFeignClient userFeignClient;

    @Override
    public PageData userClassHourStatistics(String dateTime, String teacherName, Integer page, Integer rows) {
        PageHelper.startPage(page, rows);
        List<StatisticsClassHourAO> res = pkLessonUserMapper.getStatisticsClassHourByTimeAndType(dateTime, teacherName, PkLessonUserTypeEnum.TEACHER);
        PageInfo<StatisticsClassHourAO> pageInfo = new PageInfo<>(res);
        res = pageInfo.getList();
        res.forEach(ao -> {
            ClassInfo classInfo = classInfoFeignClient.getSimpleClassInfo(ao.getClassId());
            ao.setLessonId(classInfo.getLessonId());
            ao.setLessonName(classInfo.getLessonName());
            ao.setExam(classInfo.getExam().get("name_ch"));
        });
        List<StatisticsClassHourAO> group = new ArrayList<>();
        res.stream()
                .collect(Collectors.groupingBy(
                        ao ->
                                new StatisticsClassHourAO(
                                        ao.getUserId(),
                                        ao.getUserName(),
                                        ao.getLessonName(),
                                        ao.getLessonId(),
                                        null,
                                        ao.getType(),
                                        null,
                                        ao.getExam())))
                .forEach((k, v) -> {
                    BigDecimal sum = v.stream().map(StatisticsClassHourAO::getClassHour)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    k.setClassHour(sum);
                    group.add(k);
                });
        res = group;
        PageData pageData = PageDataUtil.getPageData(pageInfo);
        pageData.setData(res);
        return pageData;
    }

    @Override
    public PageData getStudentClassHourStatistics(String dateTime, String studentName, String userAccount, Integer page, Integer rows) {
        PageHelper.startPage(page, rows);
        List<StatisticsClassHourAO> res = pkLessonUserMapper.getStatisticsClassHourByTimeAndType(dateTime, studentName, PkLessonUserTypeEnum.STUDENT);
        PageInfo<StatisticsClassHourAO> pageInfo = new PageInfo<>(res);
        List<StudentStatisticsClassHourAO> data = new ArrayList<>();
        pageInfo.getList().forEach(ao -> {
            StudentCourseInformation course = studentFeignClient.getStudentCourseInfo(ao.getUserId(), ao.getClassId(), userAccount);
            ClassInfoAdapter classInfo = classInfoFeignClient.getClassInfoById(ao.getClassId());
            StudentStatisticsClassHourAO studentStatisticsClassHourAO = formatStudentClassHourStatistics(ao, classInfo, course);
            data.add(studentStatisticsClassHourAO);
        });

        PageData pageData = PageDataUtil.getPageData(pageInfo);
        pageData.setData(data);
        return pageData;
    }

    private StudentStatisticsClassHourAO formatStudentClassHourStatistics(StatisticsClassHourAO ao, ClassInfoAdapter classInfoAdapter, StudentCourseInformation course) {
        StudentStatisticsClassHourAO studentAO = new StudentStatisticsClassHourAO();
        studentAO.setStudentId(ao.getUserId());
        studentAO.setStudentName(ao.getUserName());
        BigDecimal classHourOfTotal = new BigDecimal(0);
        if (classInfoAdapter != null) {
            studentAO.setClassId(classInfoAdapter.getId());
            studentAO.setClassName(classInfoAdapter.getClassName());
            if (classInfoAdapter.getLessonInfo() != null) {
                LessonInfo lessonInfo = classInfoAdapter.getLessonInfo();
                studentAO.setLessonId(lessonInfo.getId());
                studentAO.setLessonName(lessonInfo.getLessonName());
                studentAO.setLessonType(lessonInfo.getType());
                if (lessonInfo.getPrice() != null) {
                    studentAO.setConsultPrice(new BigDecimal(lessonInfo.getPrice()));
                }
                if (lessonInfo.getLessonClassHours() != null) {
                    classHourOfTotal = new BigDecimal(lessonInfo.getLessonClassHours());
                }

            }
            if (classInfoAdapter.getClassTeacher() != null) {
                studentAO.setMasterId(classInfoAdapter.getClassTeacher().getUserId());
                studentAO.setMasterName(classInfoAdapter.getClassTeacher().getUserName());
            }
            if (classInfoAdapter.getTeachers() != null) {
                String teacherNames = classInfoAdapter.getTeachers().stream().map(ClassUserInfo::getUserName).collect(Collectors.joining(";"));
                studentAO.setTeacherNames(teacherNames);
            }
            packingSubjects(studentAO, classInfoAdapter.getSubjectInfos());
        }
        if (course != null) {
            BigDecimal price = new BigDecimal(course.getContributionAmount());
            studentAO.setOrderTime(course.getOrderTime());
            studentAO.setOrderPrice(new BigDecimal(course.getContributionAmount()));
            if (!classHourOfTotal.equals(new BigDecimal(0))) {
                studentAO.setAveragePrice(price.divide(classHourOfTotal, 2, BigDecimal.ROUND_HALF_UP));
            }
            studentAO.setSaleId(course.getSalerId());
            String saleName = userFeignClient.getUserNameByUserId(course.getSalerId());
            studentAO.setSaleName(saleName);
        }
        if (classHourOfTotal.equals(0)) {
            studentAO.setClassHourOfSurplus(new BigDecimal(0));
        } else {
            studentAO.setClassHourOfSurplus(classHourOfTotal.subtract(ao.getClassHourOfTotal()));
        }
        studentAO.setClassHourOfMonth(ao.getClassHour());
        return studentAO;
    }

    private void packingSubjects(StudentStatisticsClassHourAO studentAO, List<LessonSubjectInfo> subjectInfos) {
        if (!CollectionUtils.isEmpty(subjectInfos)) {
            subjectInfos.forEach(
                    s -> {
                        try {
                            if (StringUtils.isNotBlank(s.getNameEn())) {
                                ExamTypeEnum type = ExamTypeEnum.valueOf(s.getNameEn());
                                switch (type) {
                                    case LISTEN:
                                        studentAO.setListen(s.getClassHour());
                                        break;
                                    case SPEAK:
                                        studentAO.setSpeak(s.getClassHour());
                                        break;
                                    case READ:
                                        studentAO.setRead(s.getClassHour());
                                        break;
                                    case WRITE:
                                        studentAO.setWrite(s.getClassHour());
                                        break;
                                    case MATHEMATICS:
                                        studentAO.setMathematics(s.getClassHour());
                                        break;
                                    case GRAMMAR:
                                        studentAO.setGrammar(s.getClassHour());
                                        break;
                                    case SCIENCE:
                                        studentAO.setScience(s.getClassHour());
                                        break;
                                    case VOCABULARY:
                                        studentAO.setVocabulary(s.getClassHour());
                                        break;
                                    case OTHERSUBJECT:
                                        studentAO.setOtherSubject(s.getClassHour());
                                        break;
                                    default:
                                        break;

                                }
                            }
                        } catch (Exception e) {

                        }
                    }
            );
        }
    }

    @Override
    public List<PkLessonUserAdapter> getStatisticsClassHourDetails(String userId, Integer classId, String dateTime, PkLessonUserTypeEnum type) {
        if (StringUtils.isEmpty(userId)) {
            return null;
        }
        if (classId == null) {
            return null;
        }
        List<Integer> classIds = new ArrayList<>();
        classIds.add(classId);
        List<PkLessonUserAdapter> res = pkLessonUserMapper.getStatisticsClassHourDetails(userId, dateTime, type, classIds);
        res.forEach(
                u -> {
                    ClassInfo classInfo = classInfoFeignClient.getSimpleClassInfo(u.getClassId());
                    if (classInfo != null) {
                        u.setClassName(classInfo.getClassName());
                        u.setBegin(DateUtil.getDTS(u.getBeginTime()));
                        u.setEnd(DateUtil.getOnlyTimeFormatStr(u.getEndTime()));
                    }
                }
        );
        return res;
    }

    @Override
    public List<PkLessonUserAdapter> getStatisticsClassHourDetailsForTeacher(String userId, Integer lessonId, String dateTime) {
        logger.info("查询用户课程下的班级lessonId={},userId={}", lessonId, userId);
        List<Integer> classIds = classInfoFeignClient.getClassInfoByLessonId(lessonId);
        logger.info("查询用户课程下的班级数据 class={}", JSON.toJSON(classIds));
        if (CollectionUtils.isEmpty(classIds)) {
            return null;
        }

        List<PkLessonUserAdapter> res = pkLessonUserMapper.getStatisticsClassHourDetails(userId, dateTime, PkLessonUserTypeEnum.TEACHER, classIds);
        res.forEach(
                u -> {
                    ClassInfo classInfo = classInfoFeignClient.getSimpleClassInfo(u.getClassId());
                    if (classInfo != null) {
                        u.setClassName(classInfo.getClassName());
                        u.setBegin(DateUtil.getDTS(u.getBeginTime()));
                        u.setEnd(DateUtil.getOnlyTimeFormatStr(u.getEndTime()));
                    }
                }
        );
        return res;
    }
}
